﻿

using BCCommon;
using BCCommon.Enums;
using BCData.Sim.Admin.StaffOrganizationMappingRecord;
using BCData.Sim.Company.JobTitle;
using BCData.Sim.Company.Position;
using BCDto.Sim.Admin.Admin;
using BCDto.Sim.Admin.StaffOrganizationMappingRecord;
using BCDto.Sim.Company.Department;
using BCEntity.Sim.Admin.StaffOrganizationMappingRecord;
using BCService.Common.Dictionary;
using BCService.Sim.Admin.Admin;
using BCService.Sim.Company.Department;
using BCService.Utils;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace BCService.Sim.Admin.StaffOrganizationMappingRecord
{
    public class StaffOrganizationMappingRecordService : IStaffOrganizationMappingRecordService
    {
        private readonly IDatabaseContext databaseContext;
        private readonly IStaffOrganizationMappingRecordData staffOrganizationMappingRecordData;
        private readonly IDepartmentService departmentService;
        private readonly IPositionData positionData;
        private readonly IJobTitleData jobTitleData;
        private readonly IAdminService adminService;
        public StaffOrganizationMappingRecordService(
            IDatabaseContext databaseContext,
            IStaffOrganizationMappingRecordData staffOrganizationMappingRecordData, 
            IDepartmentService departmentService,
            IPositionData positionData,
            IJobTitleData jobTitleData,
            IAdminService adminService)
        {
           
            this.databaseContext = databaseContext;
            this.staffOrganizationMappingRecordData = staffOrganizationMappingRecordData;
            this.departmentService = departmentService;
            this.positionData = positionData;
            this.jobTitleData = jobTitleData;
            this.adminService = adminService;
        }

        public bool Exists(long staffOrganizationMappingRecordId)
        {
            return this.staffOrganizationMappingRecordData.Exists(staffOrganizationMappingRecordId).GetAwaiter().GetResult();
        }

        public StaffOrganizationMappingRecordDto Add(StaffOrganizationMappingRecordRequestDto requestDto)
        {
            var departmentDto = this.departmentService.Get(requestDto.DepartmentId);
            if (departmentDto == null)
            {
                throw new ArgumentException("此部门不存在!");
            }

            var jobDutyDic = this.positionData.GetEntity(departmentDto.CompanyId, departmentDto.DepartmentId, requestDto.JobDutyKey).GetAwaiter().GetResult();
            var jobTitleDic = this.jobTitleData.GetEntity(requestDto.JobTitleKey).GetAwaiter().GetResult();
            if (jobDutyDic == null)
            {
                throw new ArgumentException("此职务不存在!");
            }
            if (jobTitleDic == null)
            {
                throw new ArgumentException("此职位不存在!");
            }

            var inDepartment = this.staffOrganizationMappingRecordData.Exists(departmentDto.DepartmentPath, requestDto.AdminId).GetAwaiter().GetResult();
            if(inDepartment)
            {
                var staffMappingList = this.staffOrganizationMappingRecordData.GetList(requestDto.AdminId).GetAwaiter().GetResult();
                if (staffMappingList.Any(p => departmentDto.DepartmentPath.Contains(string.Format(",{0},", p.DepartmentId)))) {
                    var mapping = staffMappingList.Single(p => departmentDto.DepartmentPath.Contains(string.Format(",{0},", p.DepartmentId)));
                    this.staffOrganizationMappingRecordData.Delete(mapping.StaffOrganizationMappingRecordId).GetAwaiter().GetResult();
                }
            }

            var adminDto = this.adminService.GetAdminInfoByAdminId(requestDto.AdminId);

            var entity = requestDto.As<StaffOrganizationMappingRecordEntity>();
            entity.CompanyId = adminDto.CompanyId;
            entity.CompanyName = adminDto.CompanyName;
            entity.DepartmentId = departmentDto.DepartmentId;
            entity.DepartmentName = departmentDto.DepartmentName;
            entity.JobDuty = jobDutyDic.PositionName;
            entity.JobTitle = jobTitleDic.JobTitle;
            entity.JobDutyKey = jobDutyDic.PositionNo;
            entity.JobTitleKey = jobTitleDic.JobTitleNo;
            entity.FullName = adminDto.FullName;
            databaseContext.BeginTransaction();
            var result = this.staffOrganizationMappingRecordData.Add(entity).GetAwaiter().GetResult();

            if (result == null)
            {
                throw new ArgumentException("添加部门员工失败!");
            }
            var departmentRequestDto = departmentDto.As<DepartmentRequestDto>();

            if (!this.departmentService.UpdateStaffCount(departmentDto.DepartmentId))
            {
                throw new ArgumentException("添加部门员工失败!");
            }
            databaseContext.Commit();
            return result.As<StaffOrganizationMappingRecordDto>();
        }

        public StaffOrganizationMappingRecordDto Update(StaffOrganizationMappingRecordPutDto putDto)
        {
            if (!this.Exists(putDto.StaffOrganizationMappingRecordId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var departmentDto = this.departmentService.Get(putDto.DepartmentId);
            if (departmentDto == null)
            {
                throw new ArgumentException("此部门不存在!");
            }

            var jobDutyDic = this.positionData.GetEntity(departmentDto.CompanyId, departmentDto.DepartmentId, putDto.JobDutyKey).GetAwaiter().GetResult();
            var jobTitleDic = this.jobTitleData.GetEntity(putDto.JobTitleKey).GetAwaiter().GetResult();
            if (jobDutyDic == null)
            {
                throw new ArgumentException("此职务不存在!");
            }
            if (jobTitleDic == null)
            {
                throw new ArgumentException("此职位不存在!");
            }
            var inDepartment = this.staffOrganizationMappingRecordData.Exists(departmentDto.DepartmentPath, putDto.AdminId).GetAwaiter().GetResult();
            if (inDepartment)
            {
                var staffMappingList = this.staffOrganizationMappingRecordData.GetList(putDto.AdminId).GetAwaiter().GetResult();
                if (staffMappingList.Any(p => departmentDto.DepartmentPath.Contains(string.Format(",{0},", p.DepartmentId))))
                {
                    var mapping = staffMappingList.Single(p => departmentDto.DepartmentPath.Contains(string.Format(",{0},", p.DepartmentId)));
                    this.staffOrganizationMappingRecordData.Delete(mapping.StaffOrganizationMappingRecordId).GetAwaiter().GetResult();
                }
            }
            var adminDto = this.adminService.GetAdminInfoByAdminId(putDto.AdminId);

            var entity = putDto.As<StaffOrganizationMappingRecordEntity>();
            entity.CompanyId = adminDto.CompanyId;
            entity.CompanyName = adminDto.CompanyName;
            entity.DepartmentId = departmentDto.DepartmentId;
            entity.DepartmentName = departmentDto.DepartmentName;
            entity.JobDuty = jobDutyDic.PositionName;
            entity.JobTitle = jobTitleDic.JobTitle;
            entity.JobDutyKey = jobDutyDic.PositionNo;
            entity.JobTitleKey = jobTitleDic.JobTitleNo;
            entity.FullName = adminDto.FullName;

            return this.staffOrganizationMappingRecordData.Update(entity).GetAwaiter().GetResult().As<StaffOrganizationMappingRecordDto>();
        }

        public bool Delete(long staffOrganizationMappingRecordId)
        {
            if (!this.Exists(staffOrganizationMappingRecordId))
            {
                throw new ArgumentException("此记录不存在!");
            }
            var staffMappingRecord = this.GetEntity(staffOrganizationMappingRecordId);
            var result = this.staffOrganizationMappingRecordData.Delete(staffOrganizationMappingRecordId).GetAwaiter().GetResult();
            if (!this.departmentService.UpdateStaffCount(staffMappingRecord.DepartmentId))
            {
                throw new ArgumentException("更新部门员工数量失败!");
            }
            return result;
        }

        public void SetActiveRole(long staffOrganizationMappingRecordId)
        {
            this.staffOrganizationMappingRecordData.SetActiveRole(staffOrganizationMappingRecordId);
        }

        public StaffOrganizationMappingRecordDto GetActiveRole(long staffOrganizationMappingRecordId)
        {
            return this.staffOrganizationMappingRecordData.GetActiveEntity(staffOrganizationMappingRecordId).GetAwaiter().GetResult().As<StaffOrganizationMappingRecordDto>();
        }

        public StaffOrganizationMappingRecordDto GetEntity(long staffOrganizationMappingRecordId)
        {
            return this.staffOrganizationMappingRecordData.GetEntity(staffOrganizationMappingRecordId).GetAwaiter().GetResult().As<StaffOrganizationMappingRecordDto>();
        }

        public StaffOrganizationMappingRecordDto GetEntityByAdminId(long adminId)
        {
            var staffList = this.staffOrganizationMappingRecordData.GetList(adminId).GetAwaiter().GetResult();
            if (staffList != null)
            {
                return staffList.First().As<StaffOrganizationMappingRecordDto>();
            }
            return null;
        }

        public IEnumerable<StaffViewDto> GetList(long adminId)
        {
            return this.staffOrganizationMappingRecordData.GetList(adminId).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }

        public IEnumerable<StaffViewDto> GetCompanyStaffList(int companyId)
        {
            return this.staffOrganizationMappingRecordData.GetCompanyStaffList(companyId).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }

        public IEnumerable<StaffViewDto> GetDepartmentStaffList(int departmentId)
        {
            return this.staffOrganizationMappingRecordData.GetDepartmentStaffList(departmentId).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }
        public IEnumerable<StaffViewDto> GetCurrentlyDepartmentStaffList(int departmentId)
        {
            return this.staffOrganizationMappingRecordData.GetCurrentlyDepartmentStaffList(departmentId).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }
        
        public IEnumerable<StaffViewDto> GetNoneStaffList(int companyId,int departmentId)
        {
            return this.staffOrganizationMappingRecordData.GetNoneStaffList(companyId, departmentId).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }
        public IEnumerable<StaffViewDto> GetJobTitleStaffList(string jobTitleKey)
        {
            return this.staffOrganizationMappingRecordData.GetJobTitleStaffList(jobTitleKey).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }
        public IEnumerable<StaffViewDto> GetStaffList(string staffName)
        {
            if (string.IsNullOrWhiteSpace(staffName))
            {
                throw new ArgumentException("请输入员工姓名");
            }
            return this.staffOrganizationMappingRecordData.GetStaffList(staffName).GetAwaiter().GetResult().As<IEnumerable<StaffViewDto>>();
        }

        public PageableList<StaffOrganizationMappingRecordDto> Query(string companyName, string departmentName, string adminName, DateTime? start, DateTime? end, int pageIndex, int pageSize)
        {
            var dataResult = this.staffOrganizationMappingRecordData.Query(companyName, departmentName, adminName, start, end, pageIndex, pageSize).GetAwaiter().GetResult();
            
            return new PageableList<StaffOrganizationMappingRecordDto>
            {
                Count = dataResult.Item2,
                Items = dataResult.Item1.As<IEnumerable<StaffOrganizationMappingRecordDto>>(),
                PageIndex = pageIndex,
                PageSize = pageSize,
                ServerTime = DateTime.Now
            };
        }

    }
}